Skip to content

Serialize curl_multi_cleanup calls for OpenSSL <1.1.0#5321

Merged
jrflat merged 3 commits intoswiftlang:mainfrom
clintonpi:serialize-multi-handle-cleanups-conditionally
Jan 13, 2026
Merged

Serialize curl_multi_cleanup calls for OpenSSL <1.1.0#5321
jrflat merged 3 commits intoswiftlang:mainfrom
clintonpi:serialize-multi-handle-cleanups-conditionally

Conversation

@clintonpi
Copy link
Contributor

Motivation:

URLSession elusively crashes due to race conditions in OpenSSL <1.1.0 when calling curl_multi_cleanup concurrently on different threads.

Modifications:

  • Add CFURLSessionSSLVersion CFURLSessionSSLVersionInfo(void) for detecting the OpenSSL version in use.
  • Adjust _MultiHandle.deinit to use a process-wide lock to serialize curl_multi_cleanup calls for environments with OpenSSL <1.1.0.

Result:

Prevents the crash while avoiding unnecessary performance overhead for newer OpenSSL versions which are thread-safe.

Testing:

Passing existing tests is sufficient. However, without this patch, the code snippet below crashes about once in 20 runs on Amazon Linux 2

$ curl --version
curl 8.3.0 (aarch64-koji-linux-gnu) libcurl/8.3.0 OpenSSL/1.0.2k-fips zlib/1.2.7 libidn2/2.3.0 libpsl/0.21.5 (+libidn2/2.3.0) libssh2/1.4.3 nghttp2/1.41.0 OpenLDAP/2.4.44
Release-Date: 2023-09-13
...

DispatchQueue.concurrentPerform(iterations: 100) { _ in
    let session: URLSession = URLSession(configuration: URLSessionConfiguration.default)
    DispatchQueue.concurrentPerform(iterations: 100) { _ in
        _ = session
    }
}

Motivation:

`URLSession` elusively crashes due to race conditions in OpenSSL <1.1.0 when calling `curl_multi_cleanup` concurrently on different threads.

Modifications:

- Add `CFURLSessionSSLVersion CFURLSessionSSLVersionInfo(void)` for detecting the OpenSSL version in use.
- Adjust `_MultiHandle.deinit` to use a process-wide lock to serialize `curl_multi_cleanup` calls for environments with OpenSSL <1.1.0.

Result:

Prevents the crash while avoiding unnecessary performance overhead for newer OpenSSL versions which are thread-safe.

Testing:

Passing existing tests is sufficient. However, without this patch, the code snippet below crashes about once in 20 runs on Amazon Linux 2
> $ curl --version
> _curl 8.3.0 (aarch64-koji-linux-gnu) libcurl/8.3.0 OpenSSL/1.0.2k-fips zlib/1.2.7 libidn2/2.3.0 libpsl/0.21.5 (+libidn2/2.3.0) libssh2/1.4.3 nghttp2/1.41.0 OpenLDAP/2.4.44_
> _Release-Date: 2023-09-13_
...
```
DispatchQueue.concurrentPerform(iterations: 100) { _ in
    let session: URLSession = URLSession(configuration: URLSessionConfiguration.default)
    DispatchQueue.concurrentPerform(iterations: 100) { _ in
        _ = session
    }
}
```
@jrflat
Copy link
Contributor

jrflat commented Dec 15, 2025

@swift-ci please test

@clintonpi clintonpi requested a review from jrflat December 18, 2025 19:57
Copy link
Contributor

@jrflat jrflat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks!

@jrflat
Copy link
Contributor

jrflat commented Jan 12, 2026

@swift-ci please test

@jrflat
Copy link
Contributor

jrflat commented Jan 13, 2026

@swift-ci please test Windows Platform

@jrflat jrflat merged commit 95e1b22 into swiftlang:main Jan 13, 2026
2 checks passed
@clintonpi clintonpi deleted the serialize-multi-handle-cleanups-conditionally branch January 13, 2026 18:33
bkhouri added a commit that referenced this pull request Jan 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants